package fast.mvc;
import fast.calc.Stats;
import fast.data.CharacterClass;
import fast.data.Spec;
import fast.loader.Profession;
import fast.loader.Race;
import fast.loader.Slot;
import fast.mvc.Controller.SpecSettingsListener;

import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.*;
import javax.swing.table.TableRowSorter;

@SuppressWarnings("serial")
public class View extends JFrame {

	String[] regionStrings = { "EU", "US", "KR", "TW", "CN" };
	private JComboBox<String> boxRegion = new JComboBox<String>(regionStrings);
	private JTextField txtServer = new JTextField("Blackmoore");
	private JTextField txtPlayer = new JTextField("Indz");
	private JButton cmdLoad = new JButton("Load");
	private JButton cmdSave = new JButton("Save Prof.");
	private JButton cmdLoadProfile = new JButton("Load Prof.");
	private JLabel labelDps = new JLabel("DPS: ");
	private JTextField txtDps = new JTextField(5);
    private JButton cmdCalc = new JButton("Recalc");
    private JButton cmdReforge = new JButton("Auto Reforge");
    private JButton cmdAutoGem = new JButton("Auto Gem");
    private static JTextArea txtLog = new JTextArea("Fast started...");
    private static JTextArea txtConsole = new JTextArea("Outputs:");
    private JScrollPane sidePanel = new JScrollPane();
    private JCheckBox showUpgrades = new JCheckBox("Show Upgrades on Gear Lists");
    private JCheckBox ignoreExp = new JCheckBox("Ignore Expertise Gems and Enchants");
    private JCheckBox combatUseRupture = new JCheckBox("Combat uses Rupture"); 
    private JLabel labelActiveSpec = new JLabel("Active Spec: ");
    private JTextField activeSpec = new JTextField(10);
    private JButton cmdChangeSpec = new JButton("Change Spec");
    private JButton cmdAltSpec = new JButton("3. Spec");
    private JButton cmdPlayer = new JButton("Player Settings");
    private JButton cmdExportReforge = new JButton("Export Reforge");
    private JButton cmdReforgeTest = new JButton("Test Reforge");
    private JButton cmdBloodfang = new JButton("Bloodfang");
    private JTable tableStats = new JTable();
    private JTable tableStatValues = new JTable();
    private JLabel labelLoading = new JLabel();
    private JScrollPane specPane = new JScrollPane();
    private SpecPanel specPanel;
    
    private HashMap<Slot,ItemSlotView> itemMap = new HashMap<Slot,ItemSlotView>();
	private ItemPanel itemPanel;
	private EnchantPanel enchantPanel;
	private GemPanel gemPanel;
	private ReforgePanel reforgePanel;
	private PlayerPanel playerPanel;
	private BreakdownPanel breakdownPanel;
    
    public View(){
        super("Fast - Rogue/Monk Calculator for Mists of Pandaria");

        initForm();
    }

    private void initForm(){
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout( null );
        this.setBounds(200, 20, 1000, 680);
        
        boxRegion.setBounds(0, 0, 60, 25);
        this.add(boxRegion);
        txtServer.setBounds(60, 0, 110, 25);
        this.add(txtServer);
        txtPlayer.setBounds(170, 0, 110, 25);
        this.add(txtPlayer);
        cmdLoad.setBounds(280, 0, 75, 25);
        this.add(cmdLoad);
        cmdCalc.setBounds(355, 0, 75, 25);
        this.add(cmdCalc);
        cmdReforge.setBounds(430, 0, 110, 25);
        this.add(cmdReforge);
        cmdAutoGem.setBounds(540, 0, 90, 25);
        this.add(cmdAutoGem);
        labelDps.setBounds(0, 30, 30, 25);
        labelDps.setHorizontalAlignment(SwingConstants.RIGHT);
        this.add(labelDps);
        txtDps.setBounds(30, 30, 60, 25);
        txtDps.setEditable(false);
        this.add(txtDps);
        
        txtLog.setEditable(true);
        txtLog.setFocusable(true);
        txtLog.setLineWrap(true);
        txtLog.setWrapStyleWord(true);
        txtLog.setFont(new Font("sansserif",Font.PLAIN,10));
        JScrollPane logPanel = new JScrollPane(txtLog);
		logPanel.getVerticalScrollBar().setUnitIncrement(20);
		logPanel.setBorder(BorderFactory.createLineBorder(java.awt.Color.black));
		logPanel.setBounds(300, 460, 340, 93);
        this.add(logPanel);
        
        JLabel itemSlotContainer = new JLabel();
        itemSlotContainer.setBounds(0, 60, 2*150, 55*9);
        itemSlotContainer.setLayout(new GridLayout(0,2,0,0));
        
        for(Slot s : Slot.viewOrder){
        	itemMap.put(s, new ItemSlotView(s));
        	itemSlotContainer.add(itemMap.get(s));
        }
        this.add(itemSlotContainer);
        
        sidePanel.setBounds(300,60,340,400);
        sidePanel.getVerticalScrollBar().setUnitIncrement(20);
        this.add(sidePanel);
        
        txtConsole.setEditable(true);
        txtConsole.setFocusable(true);
        txtConsole.setLineWrap(true);
        txtConsole.setWrapStyleWord(true);
        txtConsole.setFont(new Font("sansserif",Font.PLAIN,10));
        JScrollPane consolePanel = new JScrollPane(txtConsole);
		//logPanel.setBounds(600,430,380,200);
        consolePanel.getVerticalScrollBar().setUnitIncrement(20);
        consolePanel.setBorder(BorderFactory.createLineBorder(java.awt.Color.black));
        consolePanel.setBounds(640, 0, 240, 100);
        this.add(consolePanel);
        
        showUpgrades.setBounds(640, 100, 240, 20);
        showUpgrades.setSelected(false);
        this.add(showUpgrades);
        
        ignoreExp.setBounds(640, 120, 240, 20);
        ignoreExp.setSelected(false);
        this.add(ignoreExp);
        
        labelActiveSpec.setBounds(80, 30, 100, 25);
        labelActiveSpec.setHorizontalAlignment(SwingConstants.RIGHT);
        this.add(labelActiveSpec);
        activeSpec.setBounds(80+100, 30, 90, 25);
        activeSpec.setEditable(false);
        this.add(activeSpec);
        
        cmdChangeSpec.setBounds(80+190, 30, 110, 25);
        this.add(cmdChangeSpec);
        
        cmdAltSpec.setBounds(80+190+110, 30, 60, 25);
        cmdAltSpec.setFont(new Font("sansserif",Font.PLAIN,12));
        cmdAltSpec.setMargin(new Insets(0, 0, 0, 0));
        this.add(cmdAltSpec);
        
        cmdSave.setBounds(440, 30, 70, 25);
        cmdSave.setFont(new Font("sansserif",Font.PLAIN,12));
        cmdSave.setMargin(new Insets(0, 0, 0, 0));
        cmdSave.setVisible(false);
        this.add(cmdSave);
        
        cmdLoadProfile.setBounds(510, 30, 70, 25);
        cmdLoadProfile.setFont(new Font("sansserif",Font.PLAIN,12));
        cmdLoadProfile.setMargin(new Insets(0, 0, 0, 0));
        cmdLoadProfile.setVisible(false);
        this.add(cmdLoadProfile);
        
        cmdPlayer.setBounds(440, 30, 120, 25);
        this.add(cmdPlayer);
        
        cmdExportReforge.setBounds(0, 555, 110, 25);
        cmdExportReforge.setFont(new Font("sansserif",Font.PLAIN,12));
        cmdExportReforge.setMargin(new Insets(0, 0, 0, 0));
        this.add(cmdExportReforge);
        cmdReforgeTest.setBounds(0, 555+25, 110, 25);
        cmdReforgeTest.setFont(new Font("sansserif",Font.PLAIN,12));
        cmdReforgeTest.setMargin(new Insets(0, 0, 0, 0));
        this.add(cmdReforgeTest);
        cmdBloodfang.setBounds(0, 555+25+25, 110, 25);
        cmdBloodfang.setFont(new Font("sansserif",Font.PLAIN,12));
        cmdBloodfang.setMargin(new Insets(0, 0, 0, 0));
        this.add(cmdBloodfang);
        
        labelLoading.setBounds(599, 28, 31, 31);
		ImageIcon animatedImage = new ImageIcon( "./static/ajax-loader.gif" ); 
		labelLoading.setIcon( animatedImage ); 
		animatedImage.setImageObserver( labelLoading );
		labelLoading.setVisible(false);
		add(labelLoading);
        
        tableStats.setAutoCreateRowSorter(true);
        TableRowSorter<StatsTableModel> sorter = new TableRowSorter<StatsTableModel>();
        tableStats.setRowSorter(sorter);
        // statsTable.setModel(new StatsTableModel());
        JScrollPane scrollTable = new JScrollPane(tableStats);
        scrollTable.setBounds(640, 275, 340, 365);
        add(scrollTable);
        
        tableStatValues.setAutoCreateRowSorter(true);
        TableRowSorter<StatsTableModel> sorter2 = new TableRowSorter<StatsTableModel>();
        tableStatValues.setRowSorter(sorter2);
        JScrollPane scrollTableStatValues = new JScrollPane(tableStatValues);
        scrollTableStatValues.setBounds(640, 140, 240, 135);
        add(scrollTableStatValues);
        
        specPane.setBounds(115, 555, 500, 80);
        specPane.getVerticalScrollBar().setUnitIncrement(20);
        this.add(specPane);
        
    }

    public void resetView(){
        this.txtDps.setText("");
    }
    
    public String getRegion() {
    	return ((String) boxRegion.getSelectedItem()).toLowerCase();
    }
    
	public String getServer() {
		return txtServer.getText();
	}
	
	public String getPlayer() {
		return txtPlayer.getText();
	}

    public void setDPS(String arg){
        this.txtDps.setText(arg);
    }
    
    public static void addLog(String arg){
    	String time = Util.getTime();
		String text = View.txtLog.getText();
		if(text.equals(""))
			View.txtLog.setText(time+arg);
		else
			View.txtLog.setText(text+"\n"+time+arg);
    	//scrollen
    	View.txtLog.setCaretPosition(View.txtLog.getText().length());
    }
    
    public static void addConsole(String arg){
    	View.txtConsole.setText(View.txtConsole.getText() + "\n" + arg);
    	//scrollen
    	View.txtConsole.setCaretPosition(View.txtConsole.getText().length());
    }
    
    public void resetConsole(){
    	View.txtConsole.setText("");
    }

    public void setCalcListener(ActionListener l){
        this.cmdCalc.addActionListener(l);
    }
    
    public void setLoadListener(ActionListener l){
        this.cmdLoad.addActionListener(l);
    }
    
    public void setSaveListener(ActionListener l){
        this.cmdSave.addActionListener(l);
    }
    
    public void setLoadProfileListener(ActionListener l){
        this.cmdLoadProfile.addActionListener(l);
    }
    
    public void setAutoReforgeListener(ActionListener l){
        this.cmdReforge.addActionListener(l);
    }
    
    public void setAutoGemListener(ActionListener l){
        this.cmdAutoGem.addActionListener(l);
    }
    
	public void setSettingsListener(ActionListener l) {
		this.ignoreExp.addActionListener(l);
		this.combatUseRupture.addActionListener(l);
		this.showUpgrades.addActionListener(l);
	}
	

	public void setSpecSettingsListener(SpecSettingsListener specSettingsListener) {
		specPanel.getOptions();
	}
	
	public void setChangeSpecListener(ActionListener l) {
		this.cmdChangeSpec.addActionListener(l);
	}
	
	public void setAltSpecListener(ActionListener l) {
		this.cmdAltSpec.addActionListener(l);
	}
	
	public void setPlayerListener(ActionListener l) {
		this.cmdPlayer.addActionListener(l);
	}
	
	public void setExportReforge(ActionListener l) {
		this.cmdExportReforge.addActionListener(l);
	}
	
	public void setReforgeTest(ActionListener l) {
		this.cmdReforgeTest.addActionListener(l);
	}
	
	public void setBloodfang(ActionListener l) {
		this.cmdBloodfang.addActionListener(l);		
	}

	public HashMap<Slot,ItemSlotView> getItemMap() {
		return itemMap;
	}
	
	public JButton getAutoReforgeButton(){
		return cmdReforge;
	}
	
	public void newItemPanel() {
		itemPanel = new ItemPanel();
	}

	public void showItemPanel(Slot s) {
		sidePanel.setViewportView(itemPanel);
	}
	
	public JScrollPane getSidePanel() {
		return sidePanel;
	}
	
	public ItemPanel getItemPanel() {
		return itemPanel;
	}

	public void showEnchantPanel() {
		enchantPanel = new EnchantPanel();
		sidePanel.setViewportView(enchantPanel);
	}

	public EnchantPanel getEnchantPanel() {
		return enchantPanel;
	}

	public void showGemPanel() {
		gemPanel = new GemPanel();
		sidePanel.setViewportView(gemPanel);
	}

	public GemPanel getGemPanel() {
		return gemPanel;
	}
	
	public void showReforgePanel() {
		reforgePanel = new ReforgePanel();
		sidePanel.setViewportView(reforgePanel);
	}

	public ReforgePanel getReforgePanel() {
		return reforgePanel;
	}
	
	public void showPlayerPanel(CharacterClass cc,Race raceE,List<Profession> professions,List<String> glyphs,Set<String> talentset) {
		playerPanel = new PlayerPanel(cc,raceE,professions,glyphs,talentset);
		sidePanel.setViewportView(playerPanel);
	}
	
	public PlayerPanel getPlayerPanel() {
		return playerPanel;
	}
	
	public void showBreakdownPanel(HashMap<String, Double> map) {
		breakdownPanel = new BreakdownPanel(map);
		sidePanel.setViewportView(breakdownPanel);
	}

	public BreakdownPanel getBreakdownPanel() {
		return breakdownPanel;
	}
	
	public JCheckBox getIgnoreExp(){
		return ignoreExp;
	}
	
	public JCheckBox getCombatUseRupture(){
		return combatUseRupture;
	}
	
	public JCheckBox getShowUpgrades() {
		return showUpgrades;
	}

	public void setActiveSpec(String name) {
		activeSpec.setText(name);
	}
	
	public JTable getTableStats(){
		return tableStats;
	}
	
	public JTable getTableStatValues(){
		return tableStatValues;
	}

	public void setStats(Map<String, Double> ep, Stats stats) {
		tableStats.setModel(new StatsTableModel(ep));
		tableStats.getRowSorter().toggleSortOrder(1);
		tableStats.getRowSorter().toggleSortOrder(1);
		
		tableStatValues.setModel(new StatsTableModel(stats));
		//tableStatValues.getRowSorter().toggleSortOrder(1);
		//tableStatValues.getRowSorter().toggleSortOrder(1);
		//
	}
	
	public void resetStats() {
		setStats(new HashMap<String, Double>(), new Stats());
	}
	
	public static void showError(String msg){
		/*JOptionPane.showMessageDialog(new JFrame(),
			    msg,
			    "Error",
			    JOptionPane.ERROR_MESSAGE);*/
		View.addConsole(msg);
	}
	
	public static void warningMessage(String msg){
		JOptionPane.showMessageDialog(View.getFrames()[0],
			    msg,
			    "Warning",
			    JOptionPane.WARNING_MESSAGE);
	}

	public JLabel getLoadingImage() {
		return labelLoading;
	}

	public void showSpecPanel(Spec spec) {
		specPanel = new SpecPanel(spec);
		specPane.setViewportView(specPanel);
	}
	
	public SpecPanel getSpecPanel(){
		return specPanel;
	}
}